package com.smarttest.common.calculate;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.DecimalFormat;

/**
 * 火星02坐标 ΪWGS84坐标互转
 * 
 * @author harry.min(minzaohua@chinawayltd.com)
 * 
 */
public class Mars2Wgs {
	static final int TABLESIZE = 660 * 450;
	static double[] tableX;
	static double[] tableY;

	synchronized public static void initTable(int tableSize) throws Exception {
		double[] tableX = new double[tableSize];
		double[] tableY = new double[tableSize];
		InputStreamReader reader = new InputStreamReader(Mars2Wgs.class.getResourceAsStream("/table.dat"));
		BufferedReader br = new BufferedReader(reader);
		String s = null;
		int i = 0;
		while ((s = br.readLine()) != null) {
			String[] ss = s.split(",");
			tableX[i] = Integer.parseInt(ss[0]) / 100000.0;
			tableY[i++] = Integer.parseInt(ss[1]) / 100000.0;
			tableX[i] = Integer.parseInt(ss[2]) / 100000.0;
			tableY[i++] = Integer.parseInt(ss[3]) / 100000.0;
		}
		br.close();
		reader.close();
		
		Mars2Wgs.tableY = tableY;
		Mars2Wgs.tableX = tableX;
	}
	
	private static int id(int i, int j) {
		int id = (i)  +  660 * (j);
		return id;
	}
	
	public static double[] convert(final double x_mars, final double y_mars) {
		double[] result = new double[2];
		try {
			if (tableX == null)
				initTable(TABLESIZE);
			double xtry = x_mars;
			double ytry = y_mars;
			for (int k = 0; k < 10; ++k) {
				// 只处理中国大陆坐标
				if (xtry < 72 || xtry > 137.9 || ytry < 10 || ytry > 54.9) {
					return new double[] {xtry, ytry};
				}

				int i = (int) ((xtry - 72.0) * 10.0);
				int j = (int) ((ytry - 10.0) * 10.0);

				double x1 = tableX[id(i, j)];
				double y1 = tableY[id(i, j)];
				double x2 = tableX[id(i + 1, j)];
				double y2 = tableY[id(i + 1, j)];
				double x3 = tableX[id(i + 1, j + 1)];
				double y3 = tableY[id(i + 1, j + 1)];
				double x4 = tableX[id(i, j + 1)];
				double y4 = tableY[id(i, j + 1)];

				double t = (xtry - 72.0 - 0.1 * i) * 10.0;
				double u = (ytry - 10.0 - 0.1 * j) * 10.0;

				double dx = (1.0 - t) * (1.0 - u) * x1 + t * (1.0 - u) * x2 + t * u * x3 + (1.0 - t) * u * x4 - xtry;
				double dy = (1.0 - t) * (1.0 - u) * y1 + t * (1.0 - u) * y2 + t * u * y3 + (1.0 - t) * u * y4 - ytry;

				xtry = (xtry + x_mars - dx) / 2.0;
				ytry = (ytry + y_mars - dy) / 2.0;
			}
			result[0] = xtry;
			result[1] = ytry;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	// 标准坐标转火星坐标
	public static double[] inverse(final double x_mars, final double y_mars) {
		double[] wgs = convert(x_mars, y_mars);
		return new double[] {decimalsFormat(2 * x_mars - wgs[0]), decimalsFormat(2 * y_mars - wgs[1])}; 
	}
	
	private static DecimalFormat df=new DecimalFormat(".#######");
	private static double decimalsFormat(double d){
		String st= null;
		synchronized (df) {
			st = df.format(d);
		}
		return Double.parseDouble(st);
	}
	
	
	public static void main(String[] args) throws Exception {
		double[] mar = new double[] {120.8171109,32.0329011};
		double[] wgs = convert(mar[0], mar[1]);
		System.out.println(mar[1] + "," + mar[0]);
		System.out.println(wgs[1] + "," + wgs[0]);
		
		double[] wgs2 = inverse(mar[0], mar[1]);
		System.out.println(wgs2[1] + "," + wgs2[0]);		
	}
}
